package com.company.oa.hr.service.training.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.company.oa.common.exception.BusinessException;
import com.company.oa.hr.dto.training.PlanDTO;
import com.company.oa.hr.entity.training.Plan;
import com.company.oa.hr.mapper.training.PlanMapper;
import com.company.oa.hr.service.training.PlanService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;

@Service
public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements PlanService {

    @Override
    public IPage<Plan> getPlanPage(int page, int size, Plan plan) {
        Page<Plan> pageParam = new Page<>(page, size);
        LambdaQueryWrapper<Plan> queryWrapper = new LambdaQueryWrapper<>();

        // 添加查询条件
        queryWrapper.like(StringUtils.hasText(plan.getPlanName()), Plan::getPlanName, plan.getPlanName())
                .eq(plan.getPlanType() != null, Plan::getPlanType, plan.getPlanType())
                .eq(plan.getStatus() != null, Plan::getStatus, plan.getStatus())
                .orderByDesc(Plan::getCreateTime);

        return page(pageParam, queryWrapper);
    }

    public Plan getById(Long id) {
        return baseMapper.selectById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createPlan(PlanDTO planDTO, Long creatorId) {
        Plan plan = new Plan();
        BeanUtils.copyProperties(planDTO, plan);

        // 设置状态为草稿
        plan.setStatus(1);

        // 设置创建信息
        plan.setCreatorId(creatorId);
        plan.setCreateTime(new Date());

        return save(plan);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updatePlan(PlanDTO planDTO) {
        // 检查培训计划是否存在
        Plan existPlan = getById(planDTO.getId());
        if (existPlan == null) {
            throw new BusinessException("培训计划不存在");
        }

        // 已发布的培训计划不能修改基本信息
        if (existPlan.getStatus() != 1) {
            throw new BusinessException("已发布的培训计划不能修改基本信息");
        }

        Plan plan = new Plan();
        BeanUtils.copyProperties(planDTO, plan);

        // 设置更新时间
        plan.setUpdateTime(new Date());

        return updateById(plan);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deletePlan(Long id) {
        // 检查培训计划是否存在
        Plan existPlan = getById(id);
        if (existPlan == null) {
            throw new BusinessException("培训计划不存在");
        }

        // 已发布的培训计划不能删除
        if (existPlan.getStatus() != 1) {
            throw new BusinessException("已发布的培训计划不能删除");
        }

        return removeById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean publishPlan(Long id) {
        // 检查培训计划是否存在
        Plan existPlan = getById(id);
        if (existPlan == null) {
            throw new BusinessException("培训计划不存在");
        }

        // 只有草稿状态的培训计划可以发布
        if (existPlan.getStatus() != 1) {
            throw new BusinessException("只有草稿状态的培训计划可以发布");
        }

        Plan plan = new Plan();
        plan.setId(id);
        plan.setStatus(2); // 已发布状态
        plan.setUpdateTime(new Date());

        return updateById(plan);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cancelPlan(Long id) {
        // 检查培训计划是否存在
        Plan existPlan = getById(id);
        if (existPlan == null) {
            throw new BusinessException("培训计划不存在");
        }

        // 已完成的培训计划不能取消
        if (existPlan.getStatus() == 4) {
            throw new BusinessException("已完成的培训计划不能取消");
        }

        Plan plan = new Plan();
        plan.setId(id);
        plan.setStatus(5); // 已取消状态
        plan.setUpdateTime(new Date());

        return updateById(plan);
    }
}